{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# Connect to Label Studio"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "e22fcce0ee4a12fa"
  },
  {
   "cell_type": "code",
   "source": [
    "from label_studio_sdk.client import LabelStudio\n",
    "\n",
    "ls = LabelStudio(\n",
    "    base_url='http://localhost:8080',\n",
    "    api_key='78258cfc11b3c9f50104774d1c004842bd06bc80',\n",
    ")"
   ],
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2024-08-13T11:45:44.791239Z",
     "start_time": "2024-08-13T11:45:44.781498Z"
    }
   },
   "id": "initial_id",
   "outputs": [],
   "execution_count": 9
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Create New Project\n",
    "\n",
    "First we need to define a **Labeling Interface** for the new project:"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "39e40e7b1120c335"
  },
  {
   "cell_type": "code",
   "source": [
    "from label_studio_sdk.label_interface import LabelInterface\n",
    "from label_studio_sdk.label_interface.create import choices\n",
    "\n",
    "label_config = LabelInterface.create({\n",
    "    'text': 'Text',\n",
    "    'label': choices(['Positive', 'Negative'])\n",
    "})\n",
    "print(label_config)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-08-13T11:45:44.814719Z",
     "start_time": "2024-08-13T11:45:44.809849Z"
    }
   },
   "id": "93e728713446e20f",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<View>\n",
      "  <Text name=\"text\" value=\"$text\"/>\n",
      "  <Choices name=\"label\" toName=\"text\">\n",
      "    <Choice value=\"Positive\"/>\n",
      "    <Choice value=\"Negative\"/>\n",
      "  </Choices>\n",
      "</View>\n",
      "\n"
     ]
    }
   ],
   "execution_count": 10
  },
  {
   "cell_type": "markdown",
   "source": [
    "You can manually create [XML configuration for the labeling interface](https://labelstud.io/tags), but `LabelInterface` class provides a convenient way to create it programmatically.\n",
    "\n",
    "Now let's create a new project with the specified labeling interface:"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "79099883515b82c2"
  },
  {
   "cell_type": "code",
   "source": [
    "project = ls.projects.create(\n",
    "    title='Text Classification',\n",
    "    label_config=label_config\n",
    ")\n",
    "\n",
    "print(f'Created project:\\n{ls._client_wrapper.get_base_url()}/projects/{project.id}')"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-08-13T11:45:44.872356Z",
     "start_time": "2024-08-13T11:45:44.816740Z"
    }
   },
   "id": "7f05d9e5f6d25125",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created project:\n",
      "http://localhost:8080/projects/7\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Import Tasks to the Project"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "a106abb6cb3c42a1"
  },
  {
   "cell_type": "code",
   "source": [
    "ls.projects.import_tasks(\n",
    "    id=project.id,\n",
    "    request=[\n",
    "        {\"text\": \"Hello world\"},\n",
    "        {\"text\": \"Hello Label Studio\"},\n",
    "        {\"text\": \"What a beautiful day\"},\n",
    "    ]\n",
    ")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-08-13T11:45:44.975709Z",
     "start_time": "2024-08-13T11:45:44.874324Z"
    }
   },
   "id": "f4d556fb04165434",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ProjectsImportTasksResponse(task_count=3, annotation_count=0, predictions_count=None, duration=0.03037261962890625, file_upload_ids=[], could_be_tasks_list=False, found_formats=[], data_columns=[], prediction_count=0)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 12
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Import Tasks with Pre-annotations"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "792066fed100cbda"
  },
  {
   "cell_type": "code",
   "source": [
    "ls.projects.import_tasks(\n",
    "    id=project.id,\n",
    "    request=[\n",
    "        {\"text\": \"Hello world\", \"sentiment\": \"Positive\"},\n",
    "        {\"text\": \"Goodbye Label Studio\", \"sentiment\": \"Negative\"},\n",
    "        {\"text\": \"What a beautiful day\", \"sentiment\": \"Positive\"},\n",
    "    ],\n",
    "    preannotated_from_fields=['sentiment']\n",
    ")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-08-13T11:45:45.075813Z",
     "start_time": "2024-08-13T11:45:44.977719Z"
    }
   },
   "id": "5df9f60ae30651f8",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ProjectsImportTasksResponse(task_count=3, annotation_count=0, predictions_count=None, duration=0.029715776443481445, file_upload_ids=[], could_be_tasks_list=False, found_formats=[], data_columns=[], prediction_count=3)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 13
  },
  {
   "cell_type": "markdown",
   "source": [
    "More customizable way to import preannotations:"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "47dd92fcdab936f8"
  },
  {
   "cell_type": "code",
   "source": [
    "from label_studio_sdk.label_interface.objects import PredictionValue\n",
    "\n",
    "# this returns the same `LabelInterface` object as above\n",
    "li = ls.projects.get(id=project.id).get_label_interface()\n",
    "\n",
    "# by specifying what fields to `include` we can speed up task loading\n",
    "for task in ls.tasks.list(project=project.id, include=[\"id\"]):\n",
    "    task_id = task.id\n",
    "    prediction = PredictionValue(\n",
    "        # tag predictions with specific model version string\n",
    "        # it can help managing multiple models in Label Studio UI\n",
    "        model_version='my_model_v1',\n",
    "        # define your labels here\n",
    "        result=[\n",
    "            li.get_control('label').label(['Positive']),\n",
    "        ]\n",
    "    )\n",
    "    ls.predictions.create(task=task_id, **prediction.model_dump())\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-08-13T11:45:45.818898Z",
     "start_time": "2024-08-13T11:45:45.077904Z"
    }
   },
   "id": "687a17f9e370f275",
   "outputs": [],
   "execution_count": 14
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Export Annotations"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "58cde0e2e4659c0f"
  },
  {
   "cell_type": "code",
   "source": [
    "for task in ls.tasks.list(project=project.id):\n",
    "    print(task.id)\n",
    "    print(task.annotations)\n",
    "    print(task.predictions)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-08-13T11:45:46.003612Z",
     "start_time": "2024-08-13T11:45:45.821692Z"
    }
   },
   "id": "24e1333f469965b",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "16\n",
      "[]\n",
      "[{'id': 107, 'result': [{'id': '05776213-adb7-4f9d-a31f-43cb843f6ab3', 'from_name': 'label', 'to_name': 'text', 'type': 'choices', 'value': {'choices': ['Positive']}}], 'model_version': 'my_model_v1', 'created_ago': '0\\xa0minutes', 'score': 0.0, 'cluster': None, 'neighbors': None, 'mislabeling': 0.0, 'created_at': '2024-08-13T11:45:45.273976Z', 'updated_at': '2024-08-13T11:45:45.274003Z', 'model': None, 'model_run': None, 'task': 16, 'project': 7}]\n",
      "17\n",
      "[]\n",
      "[{'id': 108, 'result': [{'id': '0e44dfd5-18cb-4544-a6df-31c0a944d36b', 'from_name': 'label', 'to_name': 'text', 'type': 'choices', 'value': {'choices': ['Positive']}}], 'model_version': 'my_model_v1', 'created_ago': '0\\xa0minutes', 'score': 0.0, 'cluster': None, 'neighbors': None, 'mislabeling': 0.0, 'created_at': '2024-08-13T11:45:45.367334Z', 'updated_at': '2024-08-13T11:45:45.367367Z', 'model': None, 'model_run': None, 'task': 17, 'project': 7}]\n",
      "18\n",
      "[]\n",
      "[{'id': 109, 'result': [{'id': '7cf85fab-c0e5-465e-a397-5b54516547b6', 'from_name': 'label', 'to_name': 'text', 'type': 'choices', 'value': {'choices': ['Positive']}}], 'model_version': 'my_model_v1', 'created_ago': '0\\xa0minutes', 'score': 0.0, 'cluster': None, 'neighbors': None, 'mislabeling': 0.0, 'created_at': '2024-08-13T11:45:45.450186Z', 'updated_at': '2024-08-13T11:45:45.450221Z', 'model': None, 'model_run': None, 'task': 18, 'project': 7}]\n",
      "19\n",
      "[]\n",
      "[{'id': 104, 'result': [{'from_name': 'label', 'to_name': 'text', 'type': 'choices', 'value': {'choices': ['Positive']}}], 'model_version': 'undefined', 'created_ago': '0\\xa0minutes', 'score': None, 'cluster': None, 'neighbors': None, 'mislabeling': 0.0, 'created_at': '2024-08-13T11:45:45.004099Z', 'updated_at': '2024-08-13T11:45:45.004121Z', 'model': None, 'model_run': None, 'task': 19, 'project': 7}, {'id': 110, 'result': [{'id': 'c81a48ed-71bf-4058-bb1f-eee2b6e00a92', 'from_name': 'label', 'to_name': 'text', 'type': 'choices', 'value': {'choices': ['Positive']}}], 'model_version': 'my_model_v1', 'created_ago': '0\\xa0minutes', 'score': 0.0, 'cluster': None, 'neighbors': None, 'mislabeling': 0.0, 'created_at': '2024-08-13T11:45:45.528966Z', 'updated_at': '2024-08-13T11:45:45.528997Z', 'model': None, 'model_run': None, 'task': 19, 'project': 7}]\n",
      "20\n",
      "[]\n",
      "[{'id': 105, 'result': [{'from_name': 'label', 'to_name': 'text', 'type': 'choices', 'value': {'choices': ['Negative']}}], 'model_version': 'undefined', 'created_ago': '0\\xa0minutes', 'score': None, 'cluster': None, 'neighbors': None, 'mislabeling': 0.0, 'created_at': '2024-08-13T11:45:45.004157Z', 'updated_at': '2024-08-13T11:45:45.004168Z', 'model': None, 'model_run': None, 'task': 20, 'project': 7}, {'id': 111, 'result': [{'id': '946986b3-59f1-45af-b1fd-2868c1500bcd', 'from_name': 'label', 'to_name': 'text', 'type': 'choices', 'value': {'choices': ['Positive']}}], 'model_version': 'my_model_v1', 'created_ago': '0\\xa0minutes', 'score': 0.0, 'cluster': None, 'neighbors': None, 'mislabeling': 0.0, 'created_at': '2024-08-13T11:45:45.610859Z', 'updated_at': '2024-08-13T11:45:45.610895Z', 'model': None, 'model_run': None, 'task': 20, 'project': 7}]\n",
      "21\n",
      "[]\n",
      "[{'id': 106, 'result': [{'from_name': 'label', 'to_name': 'text', 'type': 'choices', 'value': {'choices': ['Positive']}}], 'model_version': 'undefined', 'created_ago': '0\\xa0minutes', 'score': None, 'cluster': None, 'neighbors': None, 'mislabeling': 0.0, 'created_at': '2024-08-13T11:45:45.004200Z', 'updated_at': '2024-08-13T11:45:45.004210Z', 'model': None, 'model_run': None, 'task': 21, 'project': 7}, {'id': 112, 'result': [{'id': 'a2598093-a978-48dd-80d0-3e1afd0afaa6', 'from_name': 'label', 'to_name': 'text', 'type': 'choices', 'value': {'choices': ['Positive']}}], 'model_version': 'my_model_v1', 'created_ago': '0\\xa0minutes', 'score': 0.0, 'cluster': None, 'neighbors': None, 'mislabeling': 0.0, 'created_at': '2024-08-13T11:45:45.691258Z', 'updated_at': '2024-08-13T11:45:45.691294Z', 'model': None, 'model_run': None, 'task': 21, 'project': 7}]\n"
     ]
    }
   ],
   "execution_count": 15
  },
  {
   "cell_type": "markdown",
   "source": [
    "Read more about task, annotations and predictions format in Label Studio [documentation](https://labelstud.io/guide/export#Label-Studio-JSON-format-of-annotated-tasks)."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "b0c80cf5bbc3ffc0"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
